namespace OpenComposite.EII.Repository
{
	using System;
	using System.Collections.Generic;
	using System.Collections.ObjectModel;
	using System.Data;
	using System.Drawing;
	using System.IO;
	using System.Text;
	using System.Windows.Forms;
	using System.Xml;
	using System.Xml.Schema;

	using OpenComposite.EII.RepositoryUIs;

	using OpenComposite.Base;
	using OpenComposite.Repository.Properties;

	[RepositoryItem(ItemType.GenericFolder, "generic_folders", "folder_id")]
	public class GenericFolder : RepositoryItemBaseEx
	{
		#region Initialization

		/// <summary>
		/// Initializes a new instance of the <see cref="GenericFolder"/> class.
		/// </summary>
		public GenericFolder()
			: base("folder_id", "folder_nm", "folder_desc", "folder_ntext", Resources.sNewGenericFolder)
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="GenericFolder"/> class.
		/// </summary>
		/// <param name="bCreateNew">if set to <c>true</c> [b create new].</param>
		public GenericFolder(bool bCreateNew)
			: this()
		{
			if ( bCreateNew )
				this.CreateNew();
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="GenericFolder"/> class.
		/// </summary>
		/// <param name="id">The id.</param>
		public GenericFolder(int id)
			: this()
		{
			this.Load(id);
		}

		#endregion Initialization

		#region Public Members

		#region Properties

		/// <summary>
		/// Gets a value indicating whether [allow drop].
		/// </summary>
		/// <value><c>true</c> if [allow drop]; otherwise, <c>false</c>.</value>
		public override bool AllowDrop
		{
			get
			{
				return true;
			}
		}

		/// <summary>
		/// Gets the allowed child types.
		/// </summary>
		/// <value>The allowed child types.</value>
		public override List<ItemType> AllowedChildTypes
		{
			get { return new List<ItemType>(this.ItemTypes); }
		}

		/// <summary>
		/// Gets the extended properties.
		/// </summary>
		/// <value>The extended properties.</value>
		public ExtendedFolderProperties ExtendedProperties
		{
			get
			{
				if ( _extProps == null ) {
					_extProps = getXmlSerializedObject<ExtendedFolderProperties>("folder_properties");
					if ( _extProps == null ) {
						_extProps = new ExtendedFolderProperties();
					}
				}
				return _extProps;
			}
		}

		/// <summary>
		/// Gets the image.
		/// </summary>
		/// <value>The image.</value>
		public override Image Image
		{
			get { return Resources.folder_closed; }
		}

		/// <summary>
		/// Gets the image key.
		/// </summary>
		/// <value>The image key.</value>
		public override string ImageKey
		{
			get
			{
				string key = "folder_closed";
				List<ItemType> types = this.AllowedChildTypes;
				if ( types.Count > 0 ) {
					if ( types.Contains(ItemType.Noun) )
						key = "vocab_folder_closed";
					else if ( types.Contains(ItemType.Capability) )
						key = "folder_closed_capability";
					else if ( types.Contains(ItemType.Verb) )
						key = "folder_closed_verb";
					else if ( types.Contains(ItemType.BObject) )
						key = "bobj_folder_closed";
					else if ( types.Contains(ItemType.BPolicy) )
						key = "policy_folder_closed";
					else if ( types.Contains(ItemType.BRule) )
						key = "brule_folder_closed";
					else if ( types.Contains(ItemType.Diagram) )
						key = "diagr_folder_closed";
					else if ( types.Contains(ItemType.Workflow) )
						key = "folder_closed_workflows";
					else if ( types.Contains(ItemType.Composite) )
						key = "folder_closed_capability";
					else if ( types.Contains(ItemType.Component) )
						key = "service_folder_closed";
					else if ( types.Contains(ItemType.System) || types.Contains(ItemType.SOBA) )
						key = "diagr_folder_closed";
					else if ( types.Contains(ItemType.WebService) )
						key = "folder_closed_webservices";
					else if ( types.Contains(ItemType.Mashup) )
						key = "folder_closed_mashup";
					else if ( types.Contains(ItemType.Business_Process) )
						key = "folder_closed_bprocess";
					else if ( types.Contains(ItemType.SOA) )
						key = "folder_closed_soa";
					else if ( types.Contains(ItemType.RuleConstant) )
						key = "folder_closed_constant";
					else if ( types.Contains(ItemType.HumanActivity) )
						key = "folder_closed_user";
					else if ( types.Contains(ItemType.LogicalMethodGroup) )
						key = "folder_closed_logmethgroup";
					else if ( types.Contains(ItemType.LogicalWebMethod) )
						key = "folder_closed_logmethod";
					else if ( types.Contains(ItemType.MessageQueue) )
						key = "folder_closed_mq";
				}
				return key;
			}
		}

		/// <summary>
		/// Gets or sets a value indicating whether this instance is user folder.
		/// </summary>
		/// <value>
		/// 	<c>true</c> if this instance is user folder; otherwise, <c>false</c>.
		/// </value>
		public bool IsUserFolder
		{
			get { return getBool("is_user_folder", true); }
			set { setValue("IsUserFolder", "is_user_folder", value); }
		}

		/// <summary>
		/// Gets or sets the item types.
		/// </summary>
		/// <value>The item types.</value>
		public ItemType[] ItemTypes
		{
			get
			{
				List<ItemType> list = new List<ItemType>();
				string types = getString("folder_types", "");
				if ( !string.IsNullOrEmpty(types) ) {
					string[] aTypes = types.Split(SEPERATOR);
					foreach ( string type in aTypes ) {
						try {
							list.Add((ItemType)Enum.Parse(typeof(ItemType), type.Trim()));
						} catch {
						}
					}
				}
				return list.ToArray();
			}
			set
			{
				string types = "";
				string sep = SEPERATOR.ToString();
				foreach ( ItemType type in value ) {
					types += ( types == "" ? "" : sep ) + ( (int)type ).ToString();
				}
				setValue("ItemTypes", "folder_types", types);
			}
		}

		/// <summary>
		/// Gets the type of the repository item.
		/// </summary>
		/// <value>The type of the repository item.</value>
		public override ItemType RepositoryItemType
		{
			get { return ItemType.GenericFolder; }
		}

		/// <summary>
		/// Gets the repository item type description.
		/// </summary>
		/// <value>The repository item type description.</value>
		public override string RepositoryItemTypeDescription
		{
			get { return ""; }
		}

		/// <summary>
		/// Gets the name of the repository item type.
		/// </summary>
		/// <value>The name of the repository item type.</value>
		public override string RepositoryItemTypeName
		{
			get { return Resources.sFolder; }
		}

		/// <summary>
		/// Gets the selected image.
		/// </summary>
		/// <value>The selected image.</value>
		public override Image SelectedImage
		{
			get { return this.Image; }
		}

		/// <summary>
		/// Gets the selected image key.
		/// </summary>
		/// <value>The selected image key.</value>
		public override string SelectedImageKey
		{
			get { return this.ImageKey; }
		}

		/// <summary>
		/// Gets the name of the table.
		/// </summary>
		/// <value>The name of the table.</value>
		public override string TableName
		{
			get { return "generic_folders"; }
		}

		#endregion Properties

		#region Methods

		/// <summary>
		/// Copies this instance.
		/// </summary>
		/// <param name="deep"><c>true</c> to recursively copy the item and all subitems;
		/// <c>false</c> to copy only the item itself.</param>
		/// <returns>The copied item.</returns>
		public override IRepositoryItem Copy(bool deep)
		{
			GenericFolder copy = new GenericFolder(true);
			copy.InitializeServiceProvider(this);
			this.CopyDataRowToTarget(copy);
			return copy;
		}

		// override
		/// <summary>
		/// Gets the icon.
		/// </summary>
		/// <returns></returns>
		public override Icon GetIcon()
		{
			Bitmap bmp = new Bitmap(this.Image);
			bmp.MakeTransparent(Color.Magenta);
			return Icon.FromHandle(bmp.GetHicon());
		}

		// new
		/// <summary>
		/// Gets the items.
		/// </summary>
		/// <returns></returns>
		public List<IRepositoryItem> GetItems()
		{
			RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			if ( repSvc == null )
				throw new NullReferenceException("RepositoryService not available.");

			List<IRepositoryItem> lstItems = new List<IRepositoryItem>();

			DataTable dt = Global.Data.GetRepositoryHierarchyChildren(this);
			if ( dt != null ) {
				foreach ( DataRow dr in dt.Rows ) {
					IRepositoryItem item = repSvc.GetItem((ItemType)dr["child_reptype_id"], (int)dr["child_id"], false);
					if ( item != null )
						lstItems.Add(item);
				}
			}
			return lstItems;
		}

		/// <summary>
		/// Gets the items.
		/// </summary>
		/// <param name="type">The type.</param>
		/// <returns></returns>
		public List<IRepositoryItem> GetItems(ItemType type)
		{
			RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			if ( repSvc == null )
				throw new NullReferenceException("RepositoryService not available.");

			List<IRepositoryItem> lstItems = new List<IRepositoryItem>();

			DataTable dt = Global.Data.GetRepositoryHierarchyChildRepositoryList(this, type);
			if ( dt != null ) {
				foreach ( DataRow dr in dt.Rows ) {
					IRepositoryItem item = repSvc.GetItem(type, dr);
					if ( item != null )
						lstItems.Add(item);
				}
			}
			return lstItems;
		}

		/// <summary>
		/// Saves this instance.
		/// </summary>
		/// <returns></returns>
		public override bool Save()
		{
			if ( _extProps != null )
				setXmlSerializedObject("ExtendedProperties", "folder_properties", _extProps);

			return base.Save();
		}

		/// <summary>
		/// Shows the new item form.
		/// </summary>
		/// <param name="idRepository">The repository ID.</param>
		/// <param name="bAllowContinue">if set to <c>true</c> to allow save and continue.</param>
		/// <param name="parentItem">The parent item.</param>
		/// <param name="idDomain">The domain ID.</param>
		/// <param name="parentItemNew">The new parent item.</param>
		/// <returns></returns>
		public override DialogResult ShowNewItemForm(int idRepository, bool bAllowContinue,
			IRepositoryItem parentItem, ref int idDomain, out IRepositoryItem parentItemNew)
		{
			FormCreateNewItem dlgNew = new FormCreateNewItem(this, this, bAllowContinue);
			dlgNew.ShowAllFolders = true;
			dlgNew.DomainID = idDomain;
			dlgNew.ParentItem = parentItem;
			//	dlgNew.FoldersVisible = false;
			DialogResult result = dlgNew.ShowDialog();
			if ( result == DialogResult.OK || result == DialogResult.Retry ) {
				idDomain = dlgNew.DomainID;
				parentItemNew = dlgNew.NewParentItem;
			} else {
				idDomain = 0;
				parentItemNew = null;
			}
			return result;
		}

		#endregion Methods

		#endregion Public Members

		#region Internal Members

		#region Constant/Read-Only Fields

		internal const string ColumnDescription = "folder_desc";
		internal const string ColumnID = "folder_id";
		internal const string ColumnNText = "folder_ntext";
		internal const string ColumnName = "folder_nm";

		#endregion Constant/Read-Only Fields

		#endregion Internal Members

		#region Protected Members

		#region Methods

		/// <summary>
		/// Sets the default values.
		/// </summary>
		protected override void SetDefaultValues()
		{
			if ( row == null )
				return;

			base.SetDefaultValues();
			this.IsUserFolder = true;
		}

		#endregion Methods

		#endregion Protected Members

		#region Private Members

		#region Constant/Read-Only Fields

		private const char SEPERATOR = ';';

		#endregion Constant/Read-Only Fields

		#region Fields

		private ExtendedFolderProperties _extProps = null;

		#endregion Fields

		#endregion Private Members
	}

	public class ExtendedFolderProperties
	{
		#region Public Members

		#region Properties

		/// <summary>
		/// Gets or sets a value indicating whether this instance is reference folder.
		/// </summary>
		/// <value>
		/// 	<c>true</c> if this instance is reference folder; otherwise, <c>false</c>.
		/// </value>
		public bool IsReferenceFolder
		{
			get { return _isReferenceFolder; }
			set { _isReferenceFolder = value; }
		}

		/// <summary>
		/// Gets or sets the reference ID.
		/// </summary>
		/// <value>The reference ID.</value>
		public int ReferenceID
		{
			get { return _idReference; }
			set { _idReference = value; }
		}

		/// <summary>
		/// Gets or sets the name of the reference.
		/// </summary>
		/// <value>The name of the reference.</value>
		public string ReferenceName
		{
			get { return _referenceName; }
			set { _referenceName = value; }
		}

		/// <summary>
		/// Gets or sets the type of the reference.
		/// </summary>
		/// <value>The type of the reference.</value>
		public ItemType ReferenceType
		{
			get { return _typeReference; }
			set { _typeReference = value; }
		}

		#endregion Properties

		#endregion Public Members

		#region Private Members

		#region Fields

		private int _idReference;
		private bool _isReferenceFolder;
		private string _referenceName;
		private ItemType _typeReference;

		#endregion Fields

		#endregion Private Members
	}
}